Provider Bulk Sync
Extend Connector
By default, the connector performs bulk and delta synchronization of OneKey HCP and HCO data to Life Sciences Cloud and Health Cloud. Use this guide only if your business requirements extend beyond standard behavior, such as splitting record types, setting affiliation roles by country, or adding field translations.
Prerequisites
- Use MuleSoft Direct in Salesforce Setup only to enable, configure, deploy, and download the out-of-the-box connector. It doesn't include an editor for mapping changes. To extend the connector, download the application code from MuleSoft Direct and edit it. After you extend it, you can no longer deploy or manage the app through MuleSoft Direct; deploy and manage it in Anypoint Platform instead.
- To modify field mapping or country-specific enhancements, see the OneKey System API documentation.
- The out-of-the-box mapping doesn't contain segmentation. To include segmentation mapping, create custom entities and fields and include the respective mapping in the System API mapping templates.
Extend Connector by Application
For Bulk Sync to work, deploy these two applications. Almost all extensions are in the first one:
| App | Role | What to extend |
|---|---|---|
OneKey System API (onekey-sys-impl) | Data retrieval, transformation, and mapping (OneKey → LSC) | The mappingTemplates/download folder (.dwl mappers and .json translation files) and a handful of onekey.download.* properties |
Provider Bulk Sync API (provider-bulk-sync-api-impl) | Salesforce writes, job orchestration, status handling, and idempotency handling | One property: lsOrg.batchManagement.individualAddress.jobName |
Separating the transformation layer from write and orchestration lets you change mappings and redeploy them without affecting the rest of the connector.
Record type IDs are config-driven (sfOrg.businessAccountRecordId and sfOrg.personAccountRecordId), so the out-of-the-box mapping already adapts to your org without a code change.
What You Can Extend
These extensions are supported:
- Anything in the
mappingTemplates/downloadfolder of the OneKey System API, the.dwlmappers and the.jsontranslation files. - These configuration properties:
- OneKey System API:
onekey.download.workplaceHierarchy,onekey.download.acceptedLicenses,onekey.download.licensesWithComplianceScope(and the record type IDs above). - Provider Bulk Sync API:
lsOrg.batchManagement.individualAddress.jobName.
- OneKey System API:
Within mappingTemplates, the .dwl scripts and .json files depend on each other. When you change a JSON file, check whether the matching .dwl needs the same update. Prefer keeping the existing JSON structure instead of reshaping it.
What Isn't Supported
Only the mapping templates and the properties listed above are meant to be changed. The items below are part of the connector's architecture rather than extension points, so changing them isn't supported and can break the sync:
- The MuleSoft application flows, and any DataWeave outside the
mappingTemplates/downloadfolder. These implement the job orchestration, Salesforce writes, status handling, and idempotency that every deployment shares. - The Anypoint MQ queue configuration (the
anypointMQblock inconfig.yaml): the queue names, and the prefetch, concurrency, and acknowledgement settings. The two applications communicate through these queues, and the names must match on both sides. See the Architecture Diagram guide for how the queues are used. - The Object Store configuration (the
objectStoreblock inconfig.yaml). The connector uses Object Store V2 to track job status, idempotency, dispatch, and completion.
The anypointMQ and objectStore blocks sit in the same config.yaml as the supported properties, so take care to change only the properties listed above. If a requirement can't be met that way, extend the mapping layer with new objects or fields in mappingTemplates rather than changing the flows or infrastructure.
1.1 Supporting Multiple HCO Record Types
Out of the box, every OneKey Workplace record maps to a single Salesforce Account HCO record type. To split them into subtypes (Hospitals, Clinics, Pharmacies, Wholesalers), extend the DataWeave mapping in the OneKey System API. The split is usually driven by the TET, LEX, and STR codes OneKey sends.
Prerequisite: Make sure record type naming is consistent across Account, HealthcareProvider, and ContactPointAddress, and configure the required record types for those entities.
How to extend:
- Go to
onekey-sys-impl→resources/mappingTemplates/download/workplaceMapper.dwl. - Find
getWorkplaceRecordType()and add conditions that read the OneKey type codes and return the matching Salesforce record type ID.
fun getWorkplaceRecordType(typeCode) =
if (typeCode == "HOSP") hospitalRecordTypeId
else if (typeCode == "PHRM") pharmacyRecordTypeId
else Mule::p('sfOrg.businessAccountRecordId')Map only the Account record type. The connector resolves record types for HealthcareProvider and ContactPointAddress during the Salesforce upsert by matching the Account record type’s developerName.
1.2 Supporting Multiple HCP Record Types
Out of the box, every OneKey Individual record maps to a single Salesforce Account HCP record type. To split them into subtypes, extend the DataWeave mapping in the OneKey System API.
Prerequisite: Make sure record type naming is consistent across Account, HealthcareProvider, and ContactPointAddress, and configure the required record types for those entities.
How to extend:
- Go to
onekey-sys-impl→resources/mappingTemplates/download/individualMapper.dwl. - Find
getIndividualRecordType()and add conditions that read the OneKey type codes and return the matching Salesforce record type ID.
fun getIndividualRecordType(typeCode) =
if (typeCode == "GMD") doctorRecordTypeId
else if (typeCode == "PHC") pharmacistRecordTypeId
else Mule::p('sfOrg.personAccountRecordId')Map only the Account record type. The connector resolves record types for HealthcareProvider and ContactPointAddress during the Salesforce upsert by matching the Account record type’s developerName.
1.3 Set Hard and Soft Affiliation Roles by Country
Out of the box, the connector treats all Activity records (HCP↔HCO) as Hard and all Individual relation records as Soft. Workplace relations are Hard when the link is a configured hierarchy type and Soft otherwise. You can decide this per country.
Workplace Relations: Set onekey.download.workplaceHierarchy.<country> to a comma-separated list of role codes that count as Hard for that country. Anything not listed maps to Soft.
onekey.download.workplaceHierarchy.IT=EMP,OWN,MAI,GRP
onekey.download.workplaceHierarchy.default=EMP,OWNIndividual Relations: These are hard-coded to Soft, so change them with a small DataWeave update:
- In
resources/mappingTemplates/download/individualMapper.dwl, replace the fixedSALESFORCE_SOFT_AFFILIATION_TYPEassignment with a function call:
"IND_RELATION_TYPE":
if (isHardRelationType(item.linkCode, country)) (SALESFORCE_HARD_AFFILIATION_TYPE)
else (SALESFORCE_SOFT_AFFILIATION_TYPE)- Add the function (it does not ship with the connector):
// Function to check if the linkCode is a hard relation type
fun isHardRelationType(linkCode, country) = ((Mule::p('onekey.download.individualRoleType.' ++ country) default Mule::p('onekey.download.individualRoleType.default')) splitBy "," contains linkCode)- Add the matching properties in
config.yaml:
onekey.download.individualRoleType.IT=MAI,GRP,INF,NFK
onekey.download.individualRoleType.default=EMP,OWN1.4 Choosing Which Country Codes Are Downloaded
Set onekey.download.codesCountryList to control which countries' reference data (codes/LOVs) is pulled. Use two-character ISO country codes.
onekey.download.codesCountryList=IT,DE,FR,ES,PL1.5 Set a Default Role When Role Is Empty
OneKey sometimes leaves the Role empty on Activities and Relations. Role is mandatory on ProviderAffiliation in LSC, and the out-of-the-box mapping has no fallback, so those records fail to insert. Add a default in the mapping.
How to extend:
wkp_relations_mappinginworkplaceMapper.dwl.ind_relations_mappinginindividualMapper.dwl.activity_base_mappinginactivityMapper.dwl.
"WKP_RELATION_ROLE": item.linkCode default <chosen default value>,
"IND_RELATION_ROLE": item.linkCode default <chosen default value>,
"ACT_ROLE": role default <chosen default value>,Setting a Default Name when usualName is Empty
Name is mandatory on the Salesforce Account and HealthcareProvider objects, and it comes from workplace.usualName, which is optional in OneKey. Some entity types in some countries arrive without it (private practices in Brazil are a known case, but it can happen anywhere OneKey leaves the name blank).
Out of the box both names are written only when usualName is present, so an empty value means no Name is sent and Salesforce rejects the record with "Missing required fields: Account.Name":
WKP_USUAL_NAME→Account.Name: Set inwkp_base_mapping, written onlyif(!isEmpty(workplace.usualName)).WKP_OFFICIAL_NAME→HealthcareProvider.Name: Set inwkp_hcp_mapping, written onlyif(!isEmpty(workplace.usualName)).
Add a fallback in wkp_base_mapping (drives Account.Name) and wkp_hcp_mapping (drives HealthcareProvider.Name):
"WKP_USUAL_NAME": record.workplace.usualName default ((record.workplace.typeCode default "HCO") ++ "-" ++ okid),
"WKP_OFFICIAL_NAME": record.workplace.usualName default ((record.workplace.typeCode default "HCO") ++ "-" ++ okid),Pick a fallback that means something to your users and is always present, for example typeCode plus a city or address label, or the OneKey ID (okid) as a guaranteed-unique last resort. Since it lives in the mapping layer, you can scope it to one country (for example, Brazil only). See Sections 1.6 and 1.11 for per-country mapping overrides.
1.6 Country-Specific Mapping Options
When your org syncs providers from more than one country, the same generic mapping doesn't always fit every region. The same OneKey attribute can arrive in a different format or carry a different meaning from one country to the next, and the values Salesforce expects differ too, for example state code formats (Section 1.9), specialty labels (Section 1.10), or which relations count as an affiliation hierarchy (Section 1.3). In these cases you give specific countries their own transformation logic while every other country keeps using the defaults, all from the same connector instance.
A single instance already handles country-specific mapping through the translation files in Section 1.11, so start there.
If a region genuinely needs its own transformation logic, the connector also supports running a dedicated MuleSoft application per region, each with its own OneKey-to-LSC mapping. Treat this as an option for large or divergent regions, not a default.
Example: sync Italy and France from one instance, where only Italy needs custom mapping:
- Preload both countries' reference codes:
onekey.download.codesCountryList=IT,FR(Section 1.4). - Create the Italy-specific files
objects_IT.json,individual_IT.json, andworkplace_IT.jsonwith the Italy overrides, for example the specialty translations from Section 1.10. Leave France with no country files. - If Italy classifies affiliations differently from the default, set
onekey.download.workplaceHierarchy.IT(Section 1.3). - Run one sync request per country, each with its own
countryCode.
During each sync, the mapper reads the record's country and loads <entity>_IT.json for Italian records. French records have no _FR files, so they fall back to the default objects.json, individual.json, and workplace.json. This is why a single instance can serve several countries at once: each record uses its country's files when present and the defaults when not.
1.7 Accepted Business Licenses
Out of the box, these codes map to Business License Compliance Scope in onekey.download.licensesWithComplianceScope. Edit the list to change which codes are included.
acceptedLicenses: "DEA,AMA,MCR,SLN,UPIN,HCE_ID,HCOS_PRFSNL_ID,IH,EH,HCOS_ORG_ID,IMS_PRSCRBR_ID,AHA,CCN,CLIA,DDD,GLN,OH_TDDD,HIN,NCPDP,PHS,TAX_ID,BTM"1.8 Business License Compliance Scope
The codes below are the ones mapped to the Business License Compliance Scope, held in onekey.download.licensesWithComplianceScope. Edit the list to change which codes are accepted.
licensesWithComplianceScope: "DEA,SLN,OH_TDDD"1.9 Map State Codes Across Countries
Out of the box, OneKey longLocalizedLabel maps to ContactPointAddress.StateCode. The format OneKey returns for a state is country-specific, so longLocalizedLabel is a valid Salesforce state code in some countries but not in others, where you map externalId instead. Don't assume either field is correct for a given country. Before you change the mapping, confirm the expected state code format for that country with IQVIA OneKey, then decide whether to map externalId or longLocalizedLabel as the State Code.
- Switch the mapping to use
externalIdfor the code, keepinglongLocalizedLabelfor the label:- State Code →
externalId(short, valid, no spaces) - State Label →
longLocalizedLabel(display only)
- State Code →
- Add these values to the State and Country/Territory Picklists in LSC
- State Code →
externalId, - State Name →
longLocalizedLabel.
- State Code →
- Redeploy the OneKey System API and rerun the Provider Bulk Sync.
This keeps State values within Salesforce's constraints so ContactPointAddress records insert successfully.
1.10 Specialty Names and Specialty Types
Out of the box the OneKey specialty code maps to CareSpecialty.SpecialtyCode, and its label maps to the Specialty Name and Type. In some regions, or for specific records, OneKey sends a null label or the raw code instead of a description, so the UI shows something like "45" or "3C" rather than a real specialty. Fix this by adding explicit translations in the attribute files.
How to extend:
- In
mappingTemplates/download/workplace.json, findWKP_SP_NAMEandWKP_SP_SPECIALITYTYPEand add the translation from the OneKey code to the LSC Specialty Name and Type. - In
mappingTemplates/download/individual.json, do the same forIND_SP_NAMEandIND_SP_SPECIALITYTYPE.
For per-country translations, create localized files following the workplace_<countryCode>.json or individual_<countryCode>.json naming convention.
1.11 OneKey-to-LSC Field Translations by Country
OneKey often sends a field as a raw code, while Life Sciences Cloud (LSC) expects a readable or restricted-picklist value. For example, WKP_HCP_TYPE_CODE arrives as "22" but ProviderType in LSC should read "Hospital". You need a translation whenever the OneKey value and the value LSC expects differ, and because those codes vary between countries, you can define the translation per country. Without one, the raw OneKey value is written as-is (or the record is skipped if the field is a restricted picklist that rejects it).
To translate OneKey attributes into LSC values across entities and fields, define the mapping in the objects.json, workplace.json, individual.json, and activity.json files.
mappingTemplates/download/objects.jsonlists the LSC entities in scope for the sync. Edit it to choose which objects are part of the integration.mappingTemplates/download/<workplace/individual/activity>.jsonholds each OneKey attribute and its target LSC fields. For any mapped field, add code-value translations using this structure:
{
"Source_Field": "<OneKey field as defined in mapper.dwl file>",
"Target_Field": "<LSC field API name>",
"CodeValues": [
{
"Source_Value": "<OneKey value 1>",
"Target_Value": "<translated value to be inserted into LSC>"
},
{
"Source_Value": "<OneKey value 2>",
"Target_Value": "<translated value to be inserted into LSC>"
}
]
}Example:
{
"Source_Field": "WKP_HCP_TYPE_CODE",
"Target_Field": "ProviderType",
"CodeValues": [
{ "Source_Value": "22", "Target_Value": "Hospital" },
{ "Source_Value": "39", "Target_Value": "Pharmacy" },
{ "Source_Value": "30", "Target_Value": "Laboratory" }
]
}For per-country implementations, create localized copies of the base files. You only need a copy for the entities a country actually overrides; every other entity keeps using the base file.
- In the OneKey System API, go to
mappingTemplates/download/, where the baseobjects.json,workplace.json,individual.json, andactivity.jsonfiles live. - Copy the base file you want to override and rename the copy with the country code, using the
objects_<countryCode>.json,workplace_<countryCode>.json,individual_<countryCode>.json, andactivity_<countryCode>.jsonnaming convention. The country code must match thecountryvalue on the record (the two-character ISO code, for exampleUS). - In the copy, change only the entries that differ for that country and leave the rest as-is.
The mapping logic picks up the country-specific file automatically during the sync, and falls back to the base file for any country that has no localized copy. For the US, for example, the files are objects_US.json, workplace_US.json, individual_US.json, and activity_US.json.
Configuration Quick Reference
This table lists every property you can change to extend the connector, so you can find the right one without reading each section. Read it as follows:
- Property is the configuration key as it appears in the application's
config.yaml. You set these values either in that file before deployment or, for the ones shown on the setup screen (such as the record type IDs), through MuleSoft Direct. - App is which of the two applications the property belongs to: the OneKey System API or the Provider Bulk Sync API.
- OOTB value is the value the connector ships with.
*(empty)*means no value is set out of the box, so you must supply one for your org; the record type IDs, for example, are set per org during setup. - Section links the property to the section above that explains what it does and how to change it.
Property keys and out-of-the-box values below were verified against onekey-sys-impl/src/main/resources/config/config.yaml and provider-bulk-sync-api-impl/src/main/resources/config/config.yaml.
| Property | App | OOTB value | Section |
|---|---|---|---|
sfOrg.businessAccountRecordId | OneKey System | (empty — set per org) | 1.1 |
sfOrg.personAccountRecordId | OneKey System | (empty — set per org) | 1.2 |
onekey.download.workplaceHierarchy.default | OneKey System | HIE,MG,GPSS | 1.3 |
onekey.download.workplaceHierarchy.US | OneKey System | HIE,MG,GPSS | 1.3 |
onekey.download.workplaceHierarchy.FR | OneKey System | HIE,GPSS | 1.3 |
onekey.download.workplaceHierarchy.IT | OneKey System | HIE,GPSS | 1.3 |
onekey.download.individualRoleType.* | OneKey System | (not present OOTB — added during 1.3) | 1.3 |
onekey.download.codesCountryList | OneKey System | (empty) | 1.4 |
onekey.download.acceptedLicenses | OneKey System | DEA,AMA,MCR,SLN,UPIN,HCE_ID,HCOS_PRFSNL_ID,IH,EH,HCOS_ORG_ID,IMS_PRSCRBR_ID,AHA,CCN,CLIA,DDD,GLN,OH_TDDD,HIN,NCPDP,PHS,TAX_ID,BTM | 1.7 |
onekey.download.licensesWithComplianceScope | OneKey System | DEA,SLN,OH_TDDD | 1.8 |
lsOrg.batchManagement.individualAddress.jobName | Provider Bulk Sync | Process_HCP_Contact_Point_Addresses | What You Can Extend |
Mapping-template files (all under onekey-sys-impl/src/main/resources/mappingTemplates/download/). The table below is a quick summary of the files this guide references. For a full description of what every template does and the fields and functions each one maps, including the codes, search, and validation templates not shown here, see the Data Mappings page in the OneKey System API documentation.
| File | Purpose | Key Functions / Fields |
|---|---|---|
workplaceMapper.dwl | Workplace (HCO) transformation | getWorkplaceRecordType, wkp_base_mapping, wkp_hcp_mapping, wkp_relations_mapping, isHierarchyType |
individualMapper.dwl | Individual (HCP) transformation | getIndividualRecordType, ind_base_mapping, ind_relations_mapping (add isHardRelationType for 1.3) |
activityMapper.dwl | Activity (HCP↔HCO affiliation) transformation | activity_base_mapping |
objects.json | Which LSC entities are in sync scope | — |
workplace.json / individual.json / activity.json | OneKey → LSC field and code-value translations | WKP_SP_NAME, IND_SP_NAME, WKP_HCP_TYPE_CODE |
Every .dwl function referenced above already exists in the connector except isHardRelationType. That's the function you add for the Section 1.3 Individual-relations extension. The Workplace Hard/Soft decision is made by the existing isHierarchyType, driven by onekey.download.workplaceHierarchy.<country>.